package yogaService

import (
	"duoke/model"
	"duoke/model/yogaModel"
	"duoke/service"
	"duoke/service/common"
	"duoke/tables"
	utils "duoke/utils/common"
	"duoke/utils/gconv"
	"duoke/utils/gjson"
	"duoke/utils/orm"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gogf/gf/v2/os/gtime"
	"strings"
)

var GroupClass = new(groupClassService)

type groupClassService struct{}

func (s *groupClassService) Save(c *gin.Context, req *yogaModel.ReqGroupClass) error {
	const (
		TableTeacher    = "yoga_teacher"
		TableGroupClass = "yoga_group_class"
		TableDate       = "yoga_school_timetable"
	)

	account, err := service.Request.Account(c)
	if account.Id == 0 || err != nil {
		return errors.New("获取用户信息失败")
	}
	get, err := orm.Db.Where("id=?", req.TeacherId).Table(TableTeacher).
		Cols("name").Get(&req.TeacherName)
	if err != nil || !get {
		return errors.New("该老师不存在")
	}
	if req.Id > 0 {
		update, err := orm.Db.Where("id=?", req.Id).Where("id=?", req.Id).
			Table(TableGroupClass).AllCols().Update(req)
		if update == 0 || err != nil {
			return errors.New("修改失败")
		} else {
			// 修改成功才修改代码
			_, err = orm.Db.In("class_type", []int{1, 2}).
				Where("class_id=?", req.Id).Table(TableDate).
				Update(map[string]string{"class_name": req.Name})
		}
	} else {
		insert, err := orm.Db.Table(TableGroupClass).Insert(req)
		if insert == 0 || err != nil {
			return errors.New("添加失败")
		}
	}
	return nil
}
func (s *groupClassService) List(c *gin.Context, req yogaModel.SearchGroupClass) (*[]yogaModel.JoinGroupClass, int64,
	error) {
	var m []yogaModel.JoinGroupClass
	where := fmt.Sprintf("reservation_date=%d and reservation_day=%d and yc.class_type=%d and yc.venue_id=%d",
		req.ReservationDate, req.ReservationDay, req.ClassType, req.VenueId)
	count, err := common.Tales.Infos(c, &model.ReqListV2{
		PageSize: req.PageSize,
		PageNo:   req.PageNo,
	}, where, "yc.id,yc.name,yc.class_type,yc.classroom,yc.difficulty,yc.duration,"+
		"yt.name as teacher_name,yc.price,yc.start_time,yc.end_time,yc.cover").Table("yoga_group_class as yc").
		Join("INNER", "yoga_date as yd", "yc.id=yd.class_id").
		Join("LEFT", "yoga_teacher as yt", "yc.teacher_id = yt.id").FindAndCount(&m)
	return &m, count, err
}
func (s *groupClassService) HotList(c *gin.Context, req *yogaModel.ReqHotList, where string) (*[]yogaModel.JoinGroupClass, int64,
	error) {
	var m []yogaModel.JoinGroupClass
	if req.SearchName != "" {
		where = fmt.Sprintf("%s and yc.name like '%s'", where, "%"+req.SearchName+"%")
	}
	count, err := common.Tales.Infos(c, &model.ReqListV2{
		PageSize: req.PageSize,
		PageNo:   req.PageNo,
	}, where, "yc.id,yc.name,yc.class_type,yc.classroom,yc.difficulty,yc.duration,"+
		"yt.name as teacher_name,yc.price,yc.start_time,yc.end_time,yc.cover").
		Table("yoga_group_class as yc").
		Join("LEFT", "yoga_teacher as yt", "yc.teacher_id = yt.id").FindAndCount(&m)
	return &m, count, err
}

func (s *groupClassService) Info(c *gin.Context, req *yogaModel.RspClassTime) (*yogaModel.GroupClassInfo, error) {
	where := fmt.Sprintf("yc.id=%d", req.FromId)
	var m yogaModel.GroupClassInfo
	get, err := common.Tales.Info(where, "yc.id,yc.name,yc.class_type,yc.classroom,yc.difficulty,"+
		"yc.duration,yt.name as teacher_name,yt.introduction as teacher_introduction,yc.price,yc.start_time,"+
		"yc.end_time,yn.lat,yn.lng,yn.name as venue_name,yt.pic as teacher_pic,content,appointment_notice,yc."+
		"venue_id,contain,sex,yc.yprice,yc.buy_count,yc.cover").Table("yoga_group_class as yc").
		Join("LEFT", "yoga_teacher as yt", "yc.teacher_id = yt.id").
		Join("LEFT", "yoga_venue as yn", "yc.venue_id = yn.id").
		Get(&m)
	if err != nil || !get {
		return nil, err
	}
	where = fmt.Sprintf("class_type=%d and class_id=%d and reservation_date=%s and reservation_day=%s",
		m.ClassType, m.Id, req.ReservationDate, req.ReservationDay)
	var d tables.YogaDate
	info, err := common.Tales.Info(where, "*").Table("yoga_date").Get(&d)
	if err != nil {
		return nil, err
	}
	classTime := fmt.Sprintf("%s%s", req.ReservationDate, req.ReservationDay)
	if info {
		var yt [2]yogaModel.TimeSlot
		gjson.Json2StructOrMap(d.ReservationMorning, &yt[0])
		gjson.Json2StructOrMap(d.ReservationAfternoon, &yt[1])
		dateString, err := utils.Common.ClassifyDateString(classTime)
		if err != nil {
			return nil, err
		}
		m.ClassTime = map[string]interface{}{
			"slot": utils.Common.GetBelongingSlot(&yt),
			"date": dateString,
			"id":   d.Id,
		}
	} else {
		m.ClassTime = map[string]interface{}{
			"slot": "暂无时间段",
			"date": "",
			"id":   0,
		}
	}
	return &m, err
}
func (s *groupClassService) DateList(c *gin.Context, id, classType int) (*[]yogaModel.ReqDate, error) {
	const TablesDate = "yoga_date"
	var m []yogaModel.ReqDate
	where := fmt.Sprintf("class_id=%d and class_type=%d",
		id, classType)
	err := common.Tales.Info(where, "*").
		Table(TablesDate).Find(&m)
	return &m, err
}
func (s *groupClassService) Infos(c *gin.Context, req *yogaModel.SearchSchoolTimetable) (*yogaModel.GroupClassInfo, error) {
	where := fmt.Sprintf("yc.id=%d", req.ClassId)
	var m yogaModel.GroupClassInfo
	get, err := common.Tales.Info(where, "yc.id,yc.name,yc.class_type,yc.classroom,yc.difficulty,"+
		"yc.duration,yt.name as teacher_name,yt.introduction as teacher_introduction,yc.price,yc.start_time,"+
		"yc.end_time,yn.lat,yn.lng,yn.name as venue_name,yt.pic as teacher_pic,content,appointment_notice,yc."+
		"venue_id,contain,sex,yc.yprice,yc.buy_count,yc.cover,yc.tag").
		Table("yoga_group_class as yc").
		Join("LEFT", "yoga_teacher as yt", "yc.teacher_id = yt.id").
		Join("LEFT", "yoga_venue as yn", "yc.venue_id = yn.id").
		Get(&m)
	if err != nil || !get {
		return nil, err
	}
	str := fmt.Sprintf("%02d", req.Day)
	classTime := fmt.Sprintf("%d%s", req.Year, str)
	week := utils.Common.Day2Week(classTime)
	var d yogaModel.ReqSchoolTimetable
	info, err := orm.Db.Where("class_type=? and class_id=? and reservation_date=? and reservation_week=?",
		req.ClassType, req.ClassId, req.Year, week).
		Table("yoga_school_timetable").Get(&d)
	if err != nil {
		return nil, err
	}
	if info {
		var yt [2]yogaModel.TimeSlot
		if d.ReservationMorning != nil {
			json := gjson.StructOrMap2Json(d.ReservationMorning)
			gjson.Json2StructOrMap(json, &yt[0])
		}
		if d.ReservationAfternoon != nil {
			json := gjson.StructOrMap2Json(d.ReservationAfternoon)
			gjson.Json2StructOrMap(json, &yt[1])
		}
		if err != nil {
			return nil, err
		}
		dateString, err := utils.Common.ClassifyDateString(classTime)
		if err != nil {
			return nil, err
		}
		m.ClassTime = map[string]interface{}{
			"slot": utils.Common.GetBelongingSlot(&yt),
			"date": dateString,
			"id":   d.Id,
		}
		m.TimeStr = utils.Common.GetBelongingSlot(&yt)
	}
	currentTime := gtime.Now().Format("15:04") // 获取 HH:mm 格式的时间
	s2 := gtime.Now().Format("Ymd")
	if m.TimeStr != "" {
		split := strings.Split(m.TimeStr, "-")
		if utils.Common.IsInTimeSlot(currentTime, split[0], split[1]) == false || gconv.Int(s2) < gconv.Int(classTime) {
			m.IsReservation = 1
		}
	}
	return &m, err
}
